package com.example.sams.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.sams.domain.enums.CourseStatus;
import com.example.sams.domain.enums.UserRole;
import com.example.sams.domain.po.*;
import com.example.sams.domain.request.EnrollCourseRequest;
import com.example.sams.domain.request.UpdateProfileRequest;
import com.example.sams.domain.vo.CourseVO;
import com.example.sams.domain.vo.StudentInfoVO;
import com.example.sams.domain.vo.TimeSlotVO;
import com.example.sams.mapper.StudentsMapper;
import com.example.sams.mapper.TeachersMapper;
import com.example.sams.service.*;
import com.example.sams.utils.ResultUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.sams.utils.UuidUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 学生表 服务实现类
 * </p>
 *
 * @author jinghong
 * @since 2025-11-04
 */
@Service
public class StudentsServiceImpl extends ServiceImpl<StudentsMapper, Students> implements IStudentsService {

    @Autowired
    private IUsersService usersService;

    @Autowired
    private IEnrollmentsService enrollmentsService;

    @Autowired
    private ICoursesService coursesService;

    @Autowired
    private TeachersMapper teachersMapper;

    @Autowired
    private ITimeSlotsService timeSlotsService;

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public ResultUtil getCurrentStudentInfo(String userId) {
        // 1. 查询用户信息
        Users user = usersService.getById(userId);
        if (user == null) {
            return ResultUtil.error("用户不存在");
        }

        // 2. 查询学生信息
        LambdaQueryWrapper<Students> studentWrapper = new LambdaQueryWrapper<>();
        studentWrapper.eq(Students::getUserId, userId);
        Students student = this.getOne(studentWrapper);
        if (student == null) {
            return ResultUtil.error("学生信息不存在");
        }

        // 3. 统计已选课程数和总学分
        LambdaQueryWrapper<Enrollments> enrollmentWrapper = new LambdaQueryWrapper<>();
        enrollmentWrapper.eq(Enrollments::getStudentId, student.getId());
        List<Enrollments> enrollments = enrollmentsService.list(enrollmentWrapper);

        int selectedCount = enrollments.size();
        int totalCredits = 0;

        for (Enrollments enrollment : enrollments) {
            Courses course = coursesService.getById(enrollment.getCourseId());
            if (course != null && course.getCredit() != null) {
                totalCredits += course.getCredit();
            }
        }

        // 4. 构建返回VO
        StudentInfoVO studentInfoVO = StudentInfoVO.builder()
                .id(student.getId())
                .name(user.getName())
                .studentNo(student.getStudentNo())
                .college(user.getCollege())
                .major(student.getMajor())
                .clazz(student.getClazz())
                .selectedCount(selectedCount)
                .totalCredits(totalCredits)
                .email(user.getEmail())
                .phone(user.getPhone())
                .grade(student.getGrade())
                .build();

        return ResultUtil.success(studentInfoVO);
    }

    @Override
    public ResultUtil getMyCourses(String userId) {
        // 1. 查询学生信息
        LambdaQueryWrapper<Students> studentWrapper = new LambdaQueryWrapper<>();
        studentWrapper.eq(Students::getUserId, userId);
        Students student = this.getOne(studentWrapper);
        if (student == null) {
            return ResultUtil.error("学生信息不存在");
        }

        // 2. 查询选课记录
        LambdaQueryWrapper<Enrollments> enrollmentWrapper = new LambdaQueryWrapper<>();
        enrollmentWrapper.eq(Enrollments::getStudentId, student.getId());
        List<Enrollments> enrollments = enrollmentsService.list(enrollmentWrapper);

        // 3. 构建课程列表
        List<CourseVO> courseVOList = new ArrayList<>();
        for (Enrollments enrollment : enrollments) {
            Courses course = coursesService.getById(enrollment.getCourseId());
            if (course == null) {
                continue;
            }

            // 查询教师信息
            String teacherName = "未知教师";
            if (course.getTeacherId() != null) {
                Teachers teacher = teachersMapper.selectById(course.getTeacherId());
                if (teacher != null) {
                    Users teacherUser = usersService.getById(teacher.getUserId());
                    if (teacherUser != null) {
                        teacherName = teacherUser.getName();
                    }
                }
            }

            // 查询时间段信息
            List<TimeSlotVO> timeSlotVOList = new ArrayList<>();
            LambdaQueryWrapper<TimeSlots> timeSlotWrapper = new LambdaQueryWrapper<>();
            timeSlotWrapper.eq(TimeSlots::getCourseId, course.getId());
            List<TimeSlots> timeSlots = timeSlotsService.list(timeSlotWrapper);

            for (TimeSlots timeSlot : timeSlots) {
                TimeSlotVO timeSlotVO = TimeSlotVO.builder()
                        .dayOfWeek(timeSlot.getDayOfWeek())
                        .start(timeSlot.getStart() != null ? timeSlot.getStart().format(DateTimeFormatter.ofPattern("HH:mm")) : null)
                        .end(timeSlot.getEnd() != null ? timeSlot.getEnd().format(DateTimeFormatter.ofPattern("HH:mm")) : null)
                        .room(timeSlot.getRoom())
                        .startWeek(timeSlot.getStartWeek())
                        .endWeek(timeSlot.getEndWeek())
                        .build();

                // 解析weeks JSON字符串为List<Integer>
                if (timeSlot.getWeeks() != null && !timeSlot.getWeeks().isEmpty()) {
                    try {
                        List<Integer> weeks = objectMapper.readValue(timeSlot.getWeeks(), new TypeReference<List<Integer>>() {});
                        timeSlotVO.setWeeks(weeks);
                    } catch (Exception e) {
                        // 如果解析失败，忽略weeks字段
                    }
                }

                timeSlotVOList.add(timeSlotVO);
            }

            CourseVO courseVO = CourseVO.builder()
                    .id(course.getId())
                    .name(course.getName())
                    .teacherName(teacherName)
                    .credit(course.getCredit())
                    .capacity(course.getCapacity())
                    .enrolledCount(course.getEnrolledCount())
                    .timeSlots(timeSlotVOList)
                    .build();

            courseVOList.add(courseVO);
        }

        return ResultUtil.success(courseVOList);
    }

    @Override
    @Transactional
    public ResultUtil enrollCourse(String userId, EnrollCourseRequest request) {
        // 1. 验证请求参数
        if (request == null || request.getCourseId() == null || request.getCourseId().trim().isEmpty()) {
            return ResultUtil.error("课程ID不能为空");
        }

        // 2. 查询学生信息
        LambdaQueryWrapper<Students> studentWrapper = new LambdaQueryWrapper<>();
        studentWrapper.eq(Students::getUserId, userId);
        Students student = this.getOne(studentWrapper);
        if (student == null) {
            return ResultUtil.error("学生信息不存在");
        }

        // 3. 查询课程信息
        Courses course = coursesService.getById(request.getCourseId());
        if (course == null) {
            return ResultUtil.error("课程不存在");
        }

        // 4. 验证课程是否已审核通过
        if (course.getStatus() != CourseStatus.approved) {
            return ResultUtil.error("课程未审核通过，无法选课");
        }

        // 5. 验证是否已选该课程
        LambdaQueryWrapper<Enrollments> checkWrapper = new LambdaQueryWrapper<>();
        checkWrapper.eq(Enrollments::getStudentId, student.getId())
                .eq(Enrollments::getCourseId, request.getCourseId());
        Enrollments existingEnrollment = enrollmentsService.getOne(checkWrapper);
        if (existingEnrollment != null) {
            return ResultUtil.error("您已选择该课程");
        }

        // 6. 验证课程容量
        if (course.getEnrolledCount() != null && course.getCapacity() != null) {
            if (course.getEnrolledCount() >= course.getCapacity()) {
                return ResultUtil.error("课程容量已满，无法选课");
            }
        }

        // 7. 创建选课记录
        Enrollments enrollment = new Enrollments();
        enrollment.setStudentId(student.getId());
        enrollment.setCourseId(request.getCourseId());
        enrollment.setEnrolledAt(LocalDateTime.now());
        enrollment.setId(UuidUtil.generateEnrollmentId());
        boolean saved = enrollmentsService.save(enrollment);
        if (!saved) {
            return ResultUtil.error("选课失败");
        }

        // 8. 更新课程的已选人数
        if (course.getEnrolledCount() == null) {
            course.setEnrolledCount(0);
        }
        course.setEnrolledCount(course.getEnrolledCount() + 1);
        coursesService.updateById(course);

        return ResultUtil.success("选课成功");
    }

    @Override
    @Transactional
    public ResultUtil dropCourse(String userId, String courseId) {
        // 1. 验证请求参数
        if (courseId == null || courseId.trim().isEmpty()) {
            return ResultUtil.error("课程ID不能为空");
        }

        // 2. 查询学生信息
        LambdaQueryWrapper<Students> studentWrapper = new LambdaQueryWrapper<>();
        studentWrapper.eq(Students::getUserId, userId);
        Students student = this.getOne(studentWrapper);
        if (student == null) {
            return ResultUtil.error("学生信息不存在");
        }

        // 3. 查询选课记录
        LambdaQueryWrapper<Enrollments> enrollmentWrapper = new LambdaQueryWrapper<>();
        enrollmentWrapper.eq(Enrollments::getStudentId, student.getId())
                .eq(Enrollments::getCourseId, courseId);
        Enrollments enrollment = enrollmentsService.getOne(enrollmentWrapper);
        if (enrollment == null) {
            return ResultUtil.error("您未选择该课程");
        }

        // 4. 删除选课记录
        boolean removed = enrollmentsService.removeById(enrollment.getId());
        if (!removed) {
            return ResultUtil.error("退课失败");
        }

        // 5. 更新课程的已选人数
        Courses course = coursesService.getById(courseId);
        if (course != null && course.getEnrolledCount() != null && course.getEnrolledCount() > 0) {
            course.setEnrolledCount(course.getEnrolledCount() - 1);
            coursesService.updateById(course);
        }

        return ResultUtil.success("退课成功");
    }

    @Override
    public ResultUtil updateProfile(String userId, UpdateProfileRequest request) {
        // 1. 验证请求参数
        if (userId == null || userId.trim().isEmpty()) {
            return ResultUtil.error("用户ID不能为空");
        }

        // 2. 查询用户信息
        Users user = usersService.getById(userId);
        if (user == null) {
            return ResultUtil.error("用户不存在");
        }

        // 3. 更新用户信息（只更新非空字段）
        boolean needUpdate = false;
        if (request.getName() != null && !request.getName().trim().isEmpty()) {
            user.setName(request.getName().trim());
            needUpdate = true;
        }
        if (request.getEmail() != null) {
            user.setEmail(request.getEmail().trim().isEmpty() ? null : request.getEmail().trim());
            needUpdate = true;
        }
        if (request.getPhone() != null) {
            user.setPhone(request.getPhone().trim().isEmpty() ? null : request.getPhone().trim());
            needUpdate = true;
        }

        // 4. 如果没有需要更新的字段，返回错误
        if (!needUpdate) {
            return ResultUtil.error("没有需要更新的字段");
        }

        // 5. 更新数据库
        boolean updated = usersService.updateById(user);
        if (!updated) {
            return ResultUtil.error("更新失败，请重试");
        }

        // 6. 返回更新后的学生信息
        return getCurrentStudentInfo(userId);
    }

    @Override
    public ResultUtil getTeacherByName(String teacherName) {
        // 1. 验证请求参数
        if (teacherName == null || teacherName.trim().isEmpty()) {
            return ResultUtil.error("教师名称不能为空");
        }

        // 2. 根据教师名称查询用户信息（只查询教师角色）
        LambdaQueryWrapper<Users> userWrapper = new LambdaQueryWrapper<>();
        userWrapper.eq(Users::getName, teacherName.trim())
                .eq(Users::getRole, UserRole.teacher);
        Users user = usersService.getOne(userWrapper);
        if (user == null) {
            return ResultUtil.error("未找到该教师信息");
        }

        // 3. 根据userId查询教师信息
        LambdaQueryWrapper<Teachers> teacherWrapper = new LambdaQueryWrapper<>();
        teacherWrapper.eq(Teachers::getUserId, user.getId());
        Teachers teacher = teachersMapper.selectOne(teacherWrapper);
        if (teacher == null) {
            return ResultUtil.error("未找到该教师信息");
        }

        // 4. 构建返回VO，包含所有可用字段
        Map<String, Object> teacherInfo = new HashMap<>();
        teacherInfo.put("id", teacher.getId());
        teacherInfo.put("name", user.getName());
        teacherInfo.put("account", teacher.getAccount());
        teacherInfo.put("college", user.getCollege());
        teacherInfo.put("title", teacher.getTitle());
        // 添加邮箱和电话字段（可能为null）
        teacherInfo.put("email", user.getEmail());
        teacherInfo.put("phone", user.getPhone());
        // 添加研究方向字段（可能为null）
        teacherInfo.put("researchArea", teacher.getResearchArea());
        // 添加简介字段（可能为null）
        teacherInfo.put("intro", teacher.getIntro());
        // 添加发表论文数字段（数据库中没有，设为null）
        teacherInfo.put("publishedPapers", null);

        return ResultUtil.success(teacherInfo);
    }
}
